/**
 * preload脚本在渲染器中加载' index.html '之前运行。
 * 它可以访问web api以及Electron的渲染处理模块和一些polyfill Node.js函数。
 * https://www.electronjs.org/docs/latest/tutorial/sandbox
 */
const { ipcRenderer } = require('electron')
const fs= require('fs')
const Store = require('electron-store')
const store = new Store()


// 常用对象
// 自动保存定时器
var saveTimer = null
// 文本输入框
var input
// 自动保存是否开启文本展示对象
var autoSave
// 字数展示对象
var wordCount
// 文字提示窗口
var dialog
// 文件保存提示窗口
var saveDialog
// 自定义自动保存时间间隔窗口
var saveCycle
// 自定义主题窗口
var customThemeDialog
// 快捷键窗口
var shortcutKeysDialog
// 关于窗口
var aboutDialog
// 搜索框
var findDialog
var findInput
var startIndex = 0; // 初始索引为0
// 替换框
var replaceDialog
var textOld
var textNew

//定位鼠标光标
function locateMouseCcursor(){
  input = document.getElementById('text')
  // 创建一个临时的Range对象
  let range = document.createRange()
  // 选择div的最后一个子节点（这里应该是文本节点）
  let lastChild = input.lastChild
  // 如果存在最后一个子节点，并且它是一个文本节点
  if (lastChild && lastChild.nodeType === Node.TEXT_NODE) {
    // 将Range的起点和终点都设置为文本节点的末尾
    range.setStart(lastChild, lastChild.textContent.length)
    range.setEnd(lastChild, lastChild.textContent.length)
    // 清除之前可能存在的选择
    let selection = window.getSelection()
    selection.removeAllRanges()
    // 将Range添加到选择中
    selection.addRange(range)
    // 为了确保光标显示，有时可能需要聚焦到div上
    input.focus()
  }
  // 如果存在滚动条，默认到底部
  input.scrollTop = input.scrollHeight;
}

// 提示框
function tips(message){
  dialog.classList.remove('fade-out')
  dialog.style.display = 'block' // 显示提示框
  dialog.innerText = message
  // 渐渐隐藏提示框
  setTimeout(function() {
    dialog.classList.add('fade-out') // 添加 fade-out 类来触发过渡效果
  }, 500)
  setTimeout(function() {
    dialog.style.display = 'none'
  }, 1000)
}

// 开启自动保存定时器
function openAutoSave(){
  let path = store.get('filePath')
  if (path) { // 自动保存数据到文件中
    saveTimer = setInterval(() => {
      fs.writeFile(path, input.innerText, (err) => {
        if (err) console.error(err);
      })
    }, store.get('intervalTime') * 60000)
  } else { // 文件不存在，将文本暂存于localStorage中防止突发情况丢失文本
    saveTimer = setInterval(() => {
      localStorage.setItem('txt', input.innerText)
    }, store.get('intervalTime') * 60000)
  }
}

// 关闭自动保存定时器
function closeAutoSave(){
  if (saveTimer) {
    clearInterval(saveTimer)
    saveTimer = null
  }
}

// 重置自动保存定时器，更新文本自动保存的位置
function resetAutoSave(){
  if (store.get('autoSave')) {
    closeAutoSave()
    openAutoSave()
  }
}

// 更新当前文本字数
function loadingWordCount(){
  wordCount.textContent = '字数：' + input.textContent.replace(/\s+/g, '').length;
}

// 关闭上一个弹窗，防止上一个弹窗未关闭情况下，打开新的弹窗
function resetPopup(){
  let dialogId = sessionStorage.getItem('dialogId')
  if (dialogId) {
    document.getElementById(dialogId).style.display = 'none'
    sessionStorage.removeItem(dialogId)
  }
}

// 查找下一个
function findNext(searchText) {
  if (searchText) {
    let oldSearchText = sessionStorage.getItem('searchText')
    if (searchText !== oldSearchText) {// 更换查找内容，更新脚标
      startIndex = 0
      sessionStorage.setItem('searchText', searchText) // 更新查找内容记录
    }
    let findMethod = sessionStorage.getItem('findMethod')
    if (findMethod && 'findNext' !== findMethod) { // 本次与查找方向不一致，处理脚标
      startIndex = startIndex + 1
    }
    sessionStorage.setItem('findMethod','findNext') // 记录本次查找方向
  } else {
    return
  }
  let contentText = input.innerHTML
  let replacement = '<span id="find-span">' + searchText + '</span>'
  contentText = contentText.replace('<span id="find-span">','').replace('</span>', '')
  // 查找下一个searchText的位置（从startIndex开始）
  let nextIndex = contentText.indexOf(searchText, startIndex)
  if (nextIndex === -1) {
    if (startIndex !== 0) { // 已经查找完一次，重新从头查找
      startIndex = 0
      nextIndex = contentText.indexOf(searchText, startIndex)
      if (nextIndex === -1) { // 重新从头查找未搜索到
        return
      }
    } else { // 查找全文未搜索到
      return
    }
  }
  // 创建一个新的文本内容，其中包含替换后的文本
  let newText = contentText.substring(0, nextIndex) + replacement + contentText.substring(nextIndex + searchText.length);
  // 更新startIndex为下一个未被替换的searchText的位置之后
  startIndex = nextIndex + searchText.length
  // 更新div的文本内容
  input.innerHTML = newText
  // 滚动条跟踪
  let childDiv = input.querySelector('#find-span'); // 获取要滚动到的特定位置的div
  childDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });

}

// 查找上一个
function findLast(searchText) {
  if (searchText) {
    let oldSearchText = sessionStorage.getItem('searchText')
    if (searchText !== oldSearchText) { // 更换查找内容，更新脚标
      startIndex = 0 // 更新脚标
      sessionStorage.setItem('searchText', searchText) // 更新查找内容记录
    }
    let findMethod = sessionStorage.getItem('findMethod')
    if (findMethod && 'findLast' !== findMethod) { // 本次与查找方向不一致，处理脚标
      startIndex = startIndex - 1
    }
    sessionStorage.setItem('findMethod','findLast') // 记录本次查找方向
  } else {
    return
  }
  let contentText = input.innerHTML
  let replacement = '<span id="find-span">' + searchText + '</span>'
  contentText = contentText.replace('<span id="find-span">','').replace('</span>', '')
  // 查找上一个searchText的位置（从startIndex开始）
  let nextIndex
  if (startIndex !== 0) {
    nextIndex = contentText.substring(0,startIndex).lastIndexOf(searchText)
    if (nextIndex === -1) { // 前半段文本内容未找到，需要从末尾查找一次
      nextIndex = contentText.lastIndexOf(searchText)
      if (nextIndex === -1) {
        return
      }
    }
  } else {// 从文本末尾直接查找
    nextIndex = contentText.lastIndexOf(searchText)
    if (nextIndex === -1) {
      return
    }
  }
  // 创建一个新的文本内容，其中包含替换后的文本
  let newText = contentText.substring(0, nextIndex) + replacement + contentText.substring(nextIndex + searchText.length);
  // 更新startIndex为下一个未被替换的searchText的位置之后
  startIndex = nextIndex
  // 更新div的文本内容
  input.innerHTML = newText
  // 滚动条跟踪
  let childDiv = input.querySelector('#find-span'); // 获取要滚动到的特定位置的div
  childDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

// 清除高亮文字
function cleanFind(){
  input.innerHTML = input.innerHTML.replace('<span id="find-span">','').replace('</span>', '')
}

// 重置文件路径及编辑区内容
function clearFilePathAndText(){
  input.textContent = '\u3000\u3000'
  localStorage.setItem('txt', '\u3000\u3000')
  locateMouseCcursor()
}

// 页面渲染完成
window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const type of ['chrome', 'node', 'electron']) {
    replaceText(`${type}-version`, process.versions[type])
  }

  /***************************** 初始化方法 *****************************/
  // 加载文本输入对象
  input = document.getElementById('text')

  // 初始化样式
  if (store.get('centerLastRow')) {
    document.body.setAttribute('center-last-row', 'center')
  } else {
    document.body.setAttribute('center-last-row', 'no')
  }

  // 设置文本字体颜色、大小，设置窗口背景颜色
  input.style.fontSize = store.get('fontSize') + 'px'
  if (store.get('color')) {
    input.style.color = store.get('color')
  }
  if (store.get('backgroundColor')) {
    document.body.style.backgroundColor = store.get('backgroundColor')
  }

  // 加载上次编辑的文件，如果文件路径不存在，则自动首行缩进定位光标
  let oldFilePath = store.get('filePath')
  if (oldFilePath) {
    fs.readFile(oldFilePath, 'utf8', (err, data) => {
      if (err) {
        store.set('filePath', null)
        clearFilePathAndText()
      } else {
        input.innerHTML = data.replace(/\n/g, '<br>')
        locateMouseCcursor() // 定位光标
        loadingWordCount() // 计算字数
      }
    })
    document.title = oldFilePath.split('\\').pop().replace('.txt', '')
    localStorage.removeItem('txt')
  } else if (localStorage.getItem('txt')){ // 未加载文件
    input.innerText = localStorage.getItem('txt')
    locateMouseCcursor()
  } else {
    clearFilePathAndText()
  }

  // 加载自动保存状态展示对象
  autoSave = document.getElementById('autoSave')
  // 判断是否开启自动保存
  if (store.get('autoSave')) {
    autoSave.textContent = '自动保存：开'
    openAutoSave()
  }

  // 加载字数展示对象
  wordCount = document.getElementById('wordCount')

  /***************************** 监听页面事件 *****************************/
  // 监听回车事件，模拟首行缩进
  input.addEventListener('keydown', function(event) {
    if (event.key === 'Enter' || event.keyCode === 13) { // 检查是否是回车键
      event.preventDefault()
      // 执行首行缩进命令
      document.execCommand('insertText', false, '\n\u3000\u3000')
    }
  })

  // 加载弹窗对象
  dialog = document.getElementById('autoCloseDialog')
  saveDialog = document.getElementById('saveDialog')
  saveCycle = document.getElementById('saveCycle')
  customThemeDialog = document.getElementById('customThemeDialog')
  shortcutKeysDialog = document.getElementById('shortcutKeysDialog')
  aboutDialog = document.getElementById('aboutDialog')
  findDialog = document.getElementById('findDialog')
  findInput = document.getElementById('findInput')
  replaceDialog = document.getElementById('replaceDialog')
  textOld = document.getElementById('textOld')
  textNew = document.getElementById('textNew')

  // 保存弹窗-保存
  document.getElementById('saveDialog-save').addEventListener('click', function() {
    let filePath =  store.get('filePath')
    saveDialog.style.display = 'none'
    if (filePath) {
      fs.writeFile(filePath, input.innerText, (err) => {
        if (err) {
          console.error(err)
          tips('保存失败');
          return
        }
        ipcRenderer.send('mainWindow-close')
      })
    } else {
      ipcRenderer.send('mainWindow-openFileWin')
    }
  })

  // 保存弹窗-不保存编
  document.getElementById('saveDialog-noSave').addEventListener('click', function() {
    saveDialog.style.display = 'none'
    ipcRenderer.send('mainWindow-close')
  })

  // 保存弹窗-取消
  document.getElementById('saveDialog-cancel').addEventListener('click', function() {
    if (store.get('autoSave')) {
      openAutoSave() // 重新启动自动保存定时器
    }
    saveDialog.style.display = 'none'
    sessionStorage.removeItem('dialogId')
  })

  // 自动保存-自定义-保存
  document.getElementById('saveCycle-save').addEventListener('click', function() {
    let intervalTime = document.getElementById('intervalTime').value
    if (intervalTime === ''){
      let saveCycleText = document.getElementById('saveCycleText')
      saveCycleText.style.display = 'block'
      saveCycleText.innerText = '请输入自动保存周期！'
      return
    }
    if (intervalTime === '0') {
      let saveCycleText = document.getElementById('saveCycleText')
      saveCycleText.style.display = 'block'
      saveCycleText.innerText = '时间间隔不能为零！'
      return
    }
    store.set('intervalTime', intervalTime)
    saveCycle.style.display = 'none'
  })

  // 自动保存-自定义-取消
  document.getElementById('saveCycle-cancel').addEventListener('click', function() {
    saveCycle.style.display = 'none'
    sessionStorage.removeItem('dialogId')
  })

  // 主题-自定义-保存
  document.getElementById('customThemeDialog-save').addEventListener('click', function() {
    let fontSize = document.getElementById('fontSize').value
    if (fontSize === ''){
      let customThemeText = document.getElementById('customThemeText')
      customThemeText.style.display = 'block'
      customThemeText.innerText = '请输入文字大小！'
      return
    }
    if (fontSize === '0') {
      let customThemeText = document.getElementById('customThemeText')
      customThemeText.style.display = 'block'
      customThemeText.innerText = '文字大小不能为零！'
      return
    }
    let color = document.getElementById('color').value
    let backgroundColor = document.getElementById('backgroundColor').value
    // 更新数据库
    store.set('fontSize', fontSize)
    store.set('color', color)
    store.set('backgroundColor', backgroundColor)
    // 更新样式
    input.style.fontSize = fontSize + 'px'
    input.style.color = color
    document.body.style.backgroundColor = backgroundColor
    customThemeDialog.style.display = 'none'
  });

  // 主题-自定义-取消
  document.getElementById('customThemeDialog-cancel').addEventListener('click', function() {
    customThemeDialog.style.display = 'none'
    sessionStorage.removeItem('dialogId')
  });

  // 快捷键-关闭
  document.getElementById('closeShortcutKeysDialog').addEventListener('click', function() {
    shortcutKeysDialog.style.display = 'none'
    sessionStorage.removeItem('dialogId')
  })

  // 关于-关闭
  document.getElementById('closeAboutDialog').addEventListener('click', function() {
    aboutDialog.style.display = 'none'
    sessionStorage.removeItem('dialogId')
  })

  // 全局搜索-查找下一个
  document.getElementById('findNext').addEventListener('click', function() {
    findNext(findInput.value)
  });

  // 全局搜索-查找上一个
  document.getElementById('findLast').addEventListener('click', function() {
    findLast(findInput.value)
  });

  // 全局搜索-关闭
  document.getElementById('closeFindDialog').addEventListener('click', function() {
    findDialog.style.display = 'none'
    startIndex = 0
    cleanFind()
    sessionStorage.removeItem('findMethod')
    sessionStorage.removeItem('dialogId')
  })

  // 全局替换-替换下一个
  document.getElementById('replaceNext').addEventListener('click', function() {
    let oldText = textOld.value
    let newText = textNew.value
    if (oldText && oldText !==newText ) {
      cleanFind()
      input.innerText = input.innerText.replace(oldText,newText)
      findNext(oldText)
    }
  });

  // 全局替换-替换上一个
  document.getElementById('replaceLast').addEventListener('click', function() {
    let oldText = textOld.value
    let newText = textNew.value
    if (oldText && oldText !==newText) {
      cleanFind()
      let text = input.innerText
      let lastIndex = text.lastIndexOf(oldText)
      if (lastIndex !== -1) {
        input.innerText = text.substring(0, lastIndex) + newText + text.substring(lastIndex + oldText.length)
        findLast(oldText)
      }
    }
  });

  // 全局替换-替换全部
  document.getElementById('replaceAll').addEventListener('click', function() {
    let oldText = textOld.value
    let newText = textNew.value
    if (oldText && oldText !==newText) {
      cleanFind()
      input.innerText = input.innerText.replaceAll(oldText,newText)
    }
  });

  // 全局替换-关闭
  document.getElementById('replaceClose').addEventListener('click', function() {
    replaceDialog.style.display = 'none'
    startIndex = 0
    cleanFind()
    sessionStorage.removeItem('findMethod')
    sessionStorage.removeItem('dialogId')
  })

  // 全局替换-替换文本与被替换文本互换位置
  document.getElementById('exchangeText').addEventListener('click', function() {
    let oldText = textOld.value
    textOld.value = textNew.value
    textNew.value = oldText
  });

  // 监听文件拖放
  ['dragover', 'drop'].forEach(eventName => {
    input.addEventListener(eventName, handleDragOverDrop, false);
  });
})

// 文字弹窗
ipcRenderer.on('tips', (event, message) => {
  tips(message)
})

// 菜单
// 文件->新建
ipcRenderer.on('clean', (event, path) => {
  store.set('filePath', null) // 清空当前编辑的文件路径
  resetAutoSave() // 重置定时器
  clearFilePathAndText()
})

// 文件->打开
ipcRenderer.on('open', (event, path, name) => {
  fs.readFile(path, 'utf8', (err, data) => {
    if (err) {
      console.error(err)
      tips('打开文件失败')
      return null
    }
    document.title = name
    input.innerHTML = data.replace(/\n/g, '<br>') // 加载文本
    locateMouseCcursor() // 定位光标
    loadingWordCount() // 计算字数
    resetAutoSave() // 文件发生变化，需要重置自动保存定时器
  })
})

/**
 * 文件->保存/另存为
 * closeTok 是否需要回调关闭窗口方法 true 关闭窗口 false 不关闭窗口
 */
ipcRenderer.on('save', (event, path, closeTok) => {
  fs.writeFile(path, input.innerText, (err) => {
    if (err) {
      console.error(err)
      tips('保存失败')
      return
    }
    if (closeTok) { // 保存成功后回调关闭窗口方法
      ipcRenderer.send('mainWindow-close')
    } else {
      tips('保存成功')
    }
  })
})

// 文件->保存-选择文件后保存
ipcRenderer.on('saveToFile', (event, path) => {
  fs.writeFile(path, input.innerText, (err) => {
    if (err) {
      console.error(err)
      tips('保存失败')
      return
    }
    resetAutoSave() // 文件发生变化，需要重置自动保存定时器
    tips('保存成功')
  })
})

// 设置->自动保存->开启
ipcRenderer.on('openAutoSave', (event) => {
  autoSave.textContent = '自动保存：开'
  store.set('autoSave', true)
  openAutoSave()
})

// 设置->自动保存->关闭
ipcRenderer.on('closeAutoSave', (event) => {
  autoSave.textContent = '自动保存：关'
  store.set('autoSave', false)
  closeAutoSave()
})

// 设置->自动保存->自定义
ipcRenderer.on('updateAutoSaveIntervalTime', (event) => {
  resetPopup()
  document.getElementById('saveCycleText').style.display = 'none'
  document.getElementById('intervalTime').value = store.get('intervalTime')
  saveCycle.style.display = 'block'
  sessionStorage.setItem('dialogId', 'saveCycle')
})

// 设置->末行居中->开启
ipcRenderer.on('openCenterLastRow', (event) => {
  store.set('centerLastRow', true)
  document.body.setAttribute('center-last-row', 'center')
})

// 设置->末行居中->关闭
ipcRenderer.on('closeCenterLastRow', (event) => {
  store.set('centerLastRow', false)
  document.body.setAttribute('center-last-row', 'no')
})

// 设置->主题->自定义
ipcRenderer.on('customThemeDialog', (event) => {
  resetPopup()
  document.getElementById('fontSize').value = store.get('fontSize')
  if (store.get('color')) {
    document.getElementById('color').value = store.get('color')
  }
  if (store.get('backgroundColor')) {
    document.getElementById('backgroundColor').value = store.get('backgroundColor')
  }
  document.getElementById('customThemeText').style.display = 'none'
  customThemeDialog.style.display = 'block'
  sessionStorage.setItem('dialogId', 'customThemeDialog')
})

// ➕ 放大字体
ipcRenderer.on('enlarge', (event) => {
  let currentFontSize = parseFloat(window.getComputedStyle(input).getPropertyValue('font-size'))
  currentFontSize = currentFontSize + 2
  input.style.fontSize = currentFontSize + 'px' // 增大2px
  store.set('fontSize', currentFontSize)
})

// ➖ 缩小字体
ipcRenderer.on('narrow', (event) => {
  let currentFontSize = parseFloat(window.getComputedStyle(input).getPropertyValue('font-size'))
  if (currentFontSize > 2) {
    currentFontSize = currentFontSize - 2
    input.style.fontSize = currentFontSize + 'px' // 减小2px，确保不小于0
    store.set('fontSize', currentFontSize)
  }
})

// 帮助->重置设置
ipcRenderer.on('reset', (event) => {
  if (store.get('autoSave')) {
    autoSave.textContent = '自动保存：关'
    closeAutoSave()
  }
  if (store.get('centerLastRow')) {
    document.body.setAttribute('center-last-row', 'no')
  }
  // 还原字体大小
  input.style.fontSize = '26px'
  // 重置所有弹窗子元素状态
  textOld.value = null
  textNew.value = null
  findInput.value = null
  document.getElementById('color').value = '#000000'
  document.getElementById('backgroundColor').value = '#FFFFFF'
})

// 帮助->快捷键
ipcRenderer.on('shortcutKeys', (event) => {
  resetPopup()
  shortcutKeysDialog.style.display = 'block'
  sessionStorage.setItem('dialogId', 'shortcutKeysDialog')
})

// 帮助->文本找回
ipcRenderer.on('restoreText', (event) => {
  let text = localStorage.getItem('txt')
  if (text && text !== '\u3000\u3000') {
    input.innerText = text
  } else {
    tips('找回失败')
  }
})

// 帮助->关于
ipcRenderer.on('about', (event) => {
  resetPopup()
  aboutDialog.style.display = 'block'
  sessionStorage.setItem('dialogId', 'aboutDialog')
})

// 关闭窗口-保存校验
ipcRenderer.on('checkSave', (event, minimize) => {
  if (store.get('autoSave')) {
    closeAutoSave() // 暂停自动保存定时器
  }
  let path = store.get('filePath')
  if (path) {
    fs.readFile(path, 'utf8', (err, data) => {
      if (err) {
        console.error(err)
      } else if (input.innerHTML === data.replace(/\n/g, '<br>')) { // 如果文本没有新的变化，直接关闭
        ipcRenderer.send('mainWindow-close')
      } else {
        resetPopup()
        saveDialog.style.display = 'block'
        sessionStorage.setItem('dialogId', 'saveDialog')
        if (minimize) { // 如果是最小化状态，打开窗口
          ipcRenderer.send('mainWindow-show')
        }
      }
    })
  } else { // 非读取文本，且当前编辑内容为空
    let text = input.innerText
    if (text && text !== '\u3000\u3000') {
      resetPopup()
      saveDialog.style.display = 'block'
      sessionStorage.setItem('dialogId', 'saveDialog')
      if (minimize) { // 如果是最小化状态，打开窗口
        ipcRenderer.send('mainWindow-show')
      }
    } else {
      ipcRenderer.send('mainWindow-close')
    }
  }
})

// 开启自动保存-重新选择文件-重置自动保存定时器-重置文本保存路径
ipcRenderer.on('resetAutoSave', (event) => {
  closeAutoSave()
  openAutoSave()
})

// 全局搜索
ipcRenderer.on('find', (e) => {
  let dialogId = sessionStorage.getItem('dialogId')
  if (dialogId && dialogId === 'replaceDialog') { // 直接从替换框切换到搜索框
    findInput.value = textOld.value // 将要替换内容自动同步到搜索框中
  }
  resetPopup()
  findDialog.style.display = 'flex'
  findInput.focus()
  sessionStorage.setItem('dialogId', 'findDialog')
})

// 全局替换
ipcRenderer.on('replace', (e) => {
  let dialogId = sessionStorage.getItem('dialogId')
  if (dialogId && dialogId === 'findDialog') { // 直接从替换框切换到搜索框
    textOld.value  = findInput.value // 将搜索内容自动同步到替换框中
  }
  resetPopup()
  replaceDialog.style.display = 'flex'
  textOld.focus()
  sessionStorage.setItem('dialogId', 'replaceDialog')
})

// 鼠标右键点击事件
window.addEventListener('contextmenu', (e) => {
  e.preventDefault()
  ipcRenderer.send('show-context-menu')
})

// 拖拽文件事件
function handleDragOverDrop(e) {
  e.preventDefault();
  e.stopPropagation();
  if (e.type === 'drop') {
    const files = e.dataTransfer.files;
    fs.readFile(files[0].path, 'utf8', (err, data) => {
      if (err) {
        console.error(err)
        return
      }
      store.set('filePath', files[0].path)
      input.innerHTML =data.replace(/\n/g, '<br>')
      locateMouseCcursor() // 定位光标
      loadingWordCount() // 计算字数
    })
  }
}
